package cn.iocoder.yudao.module.system.service.jd;

import cn.iocoder.yudao.framework.common.enums.jd.ProductionErrorCodeEnum;
import cn.iocoder.yudao.framework.common.enums.jd.ProductionStatusEnum;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.sign.SignUtil;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.jd.*;
import cn.iocoder.yudao.module.system.dal.dataobject.jd.RechargeDO;
import cn.iocoder.yudao.module.system.dal.mysql.jd.RechargeMapper;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.UNIQUEINDEX;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.JD_REMOTE_HTTP_EXCEPTION;


/**
 * 京东提交生产 Service 实现类
 *
 * @author 发起人
 */
@Service
@Validated
public class RechargeServiceImpl implements RechargeService {

    @Resource
    private RechargeMapper rechargeMapper;

    @Resource
    private RestTemplate httpRestTemplate;

    @Override
    public Integer createRecharge(RechargeSaveReqVO createReqVO) {
        // 插入
        RechargeDO recharge = BeanUtils.toBean(createReqVO, RechargeDO.class);
        recharge.setStatus(1);
        try {
            rechargeMapper.insert(recharge);
        } catch (Exception e) {
            if(e.getMessage().contains("Duplicate entry '10001' for key 'jd_order_no'")){
                return -1;
            }
        }
        // 返回
        return recharge.getId();
    }

    @Override
    public void updateRecharge(RechargeSaveReqVO updateReqVO) {
        // 校验存在
        validateRechargeExists(updateReqVO.getId());
        // 更新
        RechargeDO updateObj = BeanUtils.toBean(updateReqVO, RechargeDO.class);
        rechargeMapper.updateById(updateObj);
    }

    @Override
    public void deleteRecharge(Integer id) {
        // 校验存在
        validateRechargeExists(id);
        // 删除
        rechargeMapper.deleteById(id);
    }

    private void validateRechargeExists(Integer id) {
        if (rechargeMapper.selectById(id) == null) {
//            throw exception(RECHARGE_NOT_EXISTS);
        }
    }

    @Override
    public RechargeDO getRecharge(Integer id) {
        return rechargeMapper.selectById(id);
    }

    @Override
    public PageResult<RechargeDO> getRechargePage(RechargePageReqVO pageReqVO) {
        return rechargeMapper.selectPage(pageReqVO);
    }

    @Override
    public RechargeDO getRecharge(String jdOrderNo) {
        return rechargeMapper.getRecharge(jdOrderNo);
    }
    @Override
    public SubmitRechargeResVO beginDisstill(SubmitRechargeReqVO reqVO) {
        SubmitRechargeResVO resVO=new SubmitRechargeResVO();
        String sourceNature = reqVO.getSign();
        //签名有序性，key以字母升序排列
        Map<String, Object> treeMap = SignUtil.convertToTreeMap(reqVO);
        //构造签名
        String nature= SignUtil.buildSignature(treeMap);
        //签名比对
        if(nature.equals(sourceNature)){
            //校验生成账号是否正确
            String produceAccount = reqVO.getProduceAccount();
            boolean validationUserType = validationUserType(produceAccount);
            if (!validationUserType) {
                getSubmitRechargeResVO(resVO, ProductionErrorCodeEnum.AccountError.getCode(), ProductionStatusEnum.FAIL.getCode());
                return resVO;
            }
            resVO.setAgentOrderNo(reqVO.getWareNo());
            resVO.setJdOrderNo(Long.valueOf(reqVO.getJdOrderNo()));
            resVO.setSignType("MD5");
            RechargeDO recharge = getRecharge(reqVO.getJdOrderNo());
            if(recharge==null){
                // 保存京东提交生产的接口的参数，去重
                RechargeDO rechargeSaveReqVO=BeanUtils.toBean(reqVO, RechargeDO.class);
                List<RechargeDO> collect = Stream.of(rechargeSaveReqVO).collect(Collectors.toList());
                try {
                    rechargeMapper.insertBatch(collect);
                } catch (Exception e) {
                    if(e.getMessage().contains("Duplicate entry '10001' for key 'jd_order_no'")){
                        throw exception(UNIQUEINDEX);
                    }
                }
                if(produceAccount.contains("@")){
                    //todo 邮箱是个人账号，去天翼云创建桌面，个人用户需要创建，企业用户不需要

                }else{
                    //todo 手机号是企业账号

                }
            }

            //采用异步返回，生产接口是--生成中
            getSubmitRechargeResVO(resVO,ProductionErrorCodeEnum.PRODUCING.getCode(),ProductionStatusEnum.PRODUCING.getCode());
        }else{//失败
            getSubmitRechargeResVO(resVO,ProductionErrorCodeEnum.INVALID_SIGNATURE.getCode(),ProductionStatusEnum.FAIL.getCode());
        }
        return resVO;
    }

    @Override
    public SubmitRechargeResVO findDistill(ProductionCheckReqVO reqVO) {
        String sourceNature = reqVO.getSign();
        //签名有序性，key以字母升序排列
        Map<String, Object> treeMap = SignUtil.convertToTreeMap(reqVO);
        //构造签名
        String nature= SignUtil.buildSignature(treeMap);
        SubmitRechargeResVO resVO=new SubmitRechargeResVO();
        //签名比对
        if(nature.equals(sourceNature)){
            RechargeDO rechargeDO = getRecharge(String.valueOf(reqVO.getJdOrderNo()));
            resVO.setJdOrderNo(reqVO.getJdOrderNo());
            resVO.setSignType("MD5");
            resVO.setAgentOrderNo(rechargeDO.getWareNo());
            //生产中
            getSubmitRechargeResVO(resVO,ProductionErrorCodeEnum.PRODUCING.getCode(),ProductionStatusEnum.PRODUCING.getCode());
            //成功
//            getSubmitRechargeResVO(resVO,ProductionErrorCodeEnum.SUCCESS.getCode(),ProductionStatusEnum.SUCCESS.getCode());

            //失败
//            getSubmitRechargeResVO(resVO,ProductionErrorCodeEnum.NO_PRODUCT.getCode(),ProductionStatusEnum.FAIL.getCode());
        }else{//失败
            getSubmitRechargeResVO(resVO,ProductionErrorCodeEnum.INVALID_SIGNATURE.getCode(),ProductionStatusEnum.FAIL.getCode());
        }
        return resVO;
    }

    public void getSubmitRechargeResVO(SubmitRechargeResVO resVO, String code, Integer produceStatus) {
        resVO.setCode(code);
        resVO.setProduceStatus(produceStatus);
        long timeMillis = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        resVO.setTimestamp(sdf.format(timeMillis));
        //签名有序性，key以字母升序排列
        Map<String, Object> treeMap = SignUtil.convertToTreeMap(resVO);
        //构造签名
        String nature= SignUtil.buildSignature(treeMap);
        resVO.setSign(nature);
    }

    public boolean validationUserType(String produceAccount){
        String regex;
        if(produceAccount.contains("@")){
            regex = "^[a-zA-Z0-9_]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$";
        }else{
            //验证是否是有效手机号
            regex = "^1[3-9]\\d{9}$";
        }
        return  produceAccount.matches(regex);
    }

    /**
     * 京东回调接口异常
     */
    public HashMap<String,String> produceResult(Integer jdOrderNo,Integer produceStatus) {
//        {
//            "agentOrderNo":"45001",
//                "jdOrderNo":10002,
//                "produceStatus":1,
//                "product":"zr75dzeGdwf4MqR/6Y9oGkGYq0CBSHwhOhyCvEBK18g=",
//                "quantity":1,
//                "sign":"4ca0b45b999c1ea513c557a70b8a8865",
//                "timestamp":"20210208112401",
//                "vendorId":1201
//        }
        RechargeDO rechargeDO = getRecharge(String.valueOf(jdOrderNo));//todo 订单号
        // 请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        // 请求体
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
//        requestBody.add("agentOrderNo", "45001");
//        requestBody.add("jdOrderNo", 10002);
//        requestBody.add("produceStatus", 1);
//        requestBody.add("product", "zr75dzeGdwf4MqR/6Y9oGkGYq0CBSHwhOhyCvEBK18g=");
//        requestBody.add("quantity", 1);
//        requestBody.add("sign", "4ca0b45b999c1ea513c557a70b8a8865");
//        requestBody.add("timestamp", "20210208112401");
//        requestBody.add("vendorId", 1201);
        requestBody.add("agentOrderNo", rechargeDO.getWareNo());
        requestBody.add("jdOrderNo", Integer.parseInt(rechargeDO.getJdOrderNo()));
        requestBody.add("produceStatus",produceStatus);
        requestBody.add("product", "");//卡密为空
        requestBody.add("quantity", Integer.parseInt(rechargeDO.getQuantity()));
        long timeMillis = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        requestBody.add("timestamp", sdf.format(timeMillis));
        requestBody.add("vendorId", rechargeDO.getVendorId());
        requestBody.add("sign", "4ca0b45b999c1ea513c557a70b8a8865");
//        String url="https://vtpnotify.jd.com/vtp/produce/result";
        String url=rechargeDO.getNotifyUrl();
        // 发送请求
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
        ResponseEntity<String> responseEntity = httpRestTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
        // 处理响应
        if (!responseEntity.getStatusCode().is2xxSuccessful()) {
            throw exception(JD_REMOTE_HTTP_EXCEPTION);
        }
        return JsonUtils.parseObject(responseEntity.getBody(), HashMap.class);
    }
}